package top.lshaci.learning.springboot.jpa.config;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import top.lshaci.learning.springboot.jpa.annotation.EnableJpaResult;
import top.lshaci.learning.springboot.jpa.annotation.JpaResult;

import java.util.*;

/**
 * JpaResultConfig
 *
 * @author liangxu
 */
@Slf4j
public class JpaResultConfig implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        Set<String> packageSet = new HashSet<>();
        Map<String, Object> map = event.getApplicationContext().getBeansWithAnnotation(EnableJpaResult.class);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Class<?> beanClass = entry.getValue().getClass();
            EnableJpaResult enableJpaResult = AnnotationUtils.getAnnotation(beanClass, EnableJpaResult.class);
            if (Objects.isNull(enableJpaResult)) {
                continue;
            }
            String[] scanBasePackages = enableJpaResult.scanBasePackages();
            if (ArrayUtil.isEmpty(scanBasePackages)) {
                packageSet.add(beanClass.getPackage().getName());
            } else {
                packageSet.addAll(Arrays.asList(scanBasePackages));
            }
        }
        if (CollUtil.isEmpty(packageSet)) {
            return;
        }
        System.err.println(packageSet);
        GenericConversionService genericConversionService = ((GenericConversionService) DefaultConversionService.getSharedInstance());
        for (String packageName : packageSet) {
            addConverter(packageName, genericConversionService);
        }

    }

    private void addConverter(String packageName, GenericConversionService genericConversionService) {
        Set<Class<?>> jpaResultClass = ClassUtil.scanPackageByAnnotation(packageName, JpaResult.class);
        if (CollUtil.isEmpty(jpaResultClass)) {
            return;
        }

        for (Class cls : jpaResultClass) {
            log.info("Jpa添加Converter,class={}", cls.getName());
            genericConversionService.addConverter(Object.class, cls, s -> {
                System.err.println("source:" + s);
                Object o = BeanUtil.toBeanIgnoreCase(s, cls, false);
                System.err.println("target:" + o);
                return o;
            });
        }
    }

//    @PostConstruct
//    public void init() {
//        String packageName = "top.lshaci.learning.springboot.jpa";
//        Set<Class<?>> jpaResultClass = ClassUtil.scanPackageByAnnotation(packageName, JpaResult.class);
//        GenericConversionService genericConversionService = ((GenericConversionService) DefaultConversionService.getSharedInstance());
//        for (Class cls : jpaResultClass) {
//            log.info("Jpa添加Converter,class={}", cls.getName());
//            genericConversionService.addConverter(Object.class, cls, s -> {
//                System.err.println("source:" + s);
//                Object o = BeanUtil.toBeanIgnoreCase(s, cls, false);
//                System.err.println("target:" + o);
//                return o;
//            });
//        }
//    }

}
